#include<iostream>
#include<mutex>
#include<thread>
#include<condition_variable>
using namespace std;

int main()
{
  mutex mtx;
  condition_variable_any cv;
  bool flag = false;
  int i = 1;
  //flag = false print
  thread t1([&]{
    while(i < 100)
    {
      unique_lock<mutex> ul(mtx); 
      cv.wait(ul,[&flag]()->bool{return !flag;});
      cout <<std::this_thread::get_id() <<" :" << i <<endl;
      flag = true;
      i++;
      cv.notify_one();
    }
      });
  thread t2([&]{
    while(i < 100)
    {
      unique_lock<mutex> ul(mtx); 
      cv.wait(ul,[&flag]()->bool{return flag;});
      cout <<std::this_thread::get_id() <<" :" << i <<endl;
      flag = false;
      i++;
      cv.notify_one();
    }
      });

  t1.join();
  t2.join();
  return 0;
}

/*
#include<iostream>
using namespace std;

//int main()
//{
//	int a = 10;
//	int b = 20;
//
//	//const int *p  <==> int const *p 下面相当于是重复定义==>多次使用同一类型限定符
//	//相当于是: const const int* p = &a
//	//const int const* p = &a; 
//	//p = &b; //ok
//
//	//正确写法：
//	const int* const p = &a;
//	//p = &b;//err
//	return 0;
//}

////前置声明,否则下面无法识别这两个类型
//class A;
//class B;
//
//class A
//{
//public:
//	A() { cout << "A()" << endl; }
//	~A() { cout << "~A()" << endl; }
//	void testA()
//	{
//		cout << "一个好用的方法" << endl;
//	}
//	weak_ptr<B> ptrB;
//};
//class B
//{
//public:
//	B() { cout << "B()" << endl; }
//	~B() { cout << "~B()" << endl; }
//	void func()
//	{
//		shared_ptr<A> ps = ptrA.lock();
//		if (ps != nullptr) //提升成功
//			ps->testA();
//	}
//	weak_ptr<A> ptrA;
//};


//int main()
//{
//	shared_ptr<A> pa(new A());
//	shared_ptr<B> pb(new B());
//
//	pa->ptrB = pb;
//	pb->ptrA = pa;
//
//	//查看pa和pb管理的资源的引用计数情况
//	cout << pa.use_count() << endl;//1
//	cout << pb.use_count() << endl;//1
//	return 0;
//}
#include<thread>
#include<memory>
//class A
//{
//public:
//	A() { cout << "A()" << endl; }
//	~A() { cout << "~A()" << endl; }
//	void testA() { cout << "A::testA()" << endl; }
//};
//void handle(weak_ptr<A> pw)
//{
//	std::this_thread::sleep_for(std::chrono::seconds(2)); //休眠2s
//	shared_ptr<A> sp = pw.lock();
//	if (sp != nullptr)
//		sp->testA();
//	else
//		cout << "A对象已经析构...." << endl;
//}
//int main()
//{
//	{
//		shared_ptr<A> p(new A());
//		thread t1(handle, weak_ptr<A>(p));
//		t1.detach();
//	}
//	//出作用域只会,p指向的资源就会释放
//
//	std::this_thread::sleep_for(std::chrono::seconds(5)); //休眠5s
//	return 0;
//}

//销毁单个元素对象
template<class T>
struct DeleteOneEle
{
	void operator()(T* p)
	{
		cout << "Delete::operator()(T* p)" << endl;
		delete p;
	}
};
//销毁new出来的数组
template<class T>
struct DeleteArr
{
	void operator()(T* p)
	{
		cout << "DeleteArr::operator()(T* p)" << endl;
		delete[] p;
	}
};


//销毁文件指针
template<class T>
struct DeleteFile
{
	void operator()(T* p)
	{
		cout << "DeleteFile::operator()(T* p)" << endl;
		fclose(p);
	}
};

//
//int main()
//{
//	shared_ptr<int> sp1(new int(10)); //默认以delete的方式释放资源
//	shared_ptr<int> sp2(new int(20), DeleteOneEle<int>());
//	shared_ptr<int> sp3(new int[10], DeleteArr<int>());
//	shared_ptr<FILE> sp4(fopen("./data.txt","w"), DeleteFile<FILE>());
//
//
//	unique_ptr<int> uq1(new int(10));
//	unique_ptr<int, DeleteArr<int>> uq2(new int[20]);
//	unique_ptr<FILE, DeleteFile<FILE>> uq3(fopen("./data.txt","w"));
//	return 0;
//}

//#include <iostream>
//#include <thread>
//#include <atomic>	//包含了很多原子类型
//#include <list>
//using namespace std;
//
//volatile std::atomic_bool isReady = false;
//volatile std::atomic_int mycount = 0;
//
//void task()
//{
//	while (!isReady)//还没有准备好 
//	{
//		std::this_thread::yield();//线程出让当前的CPU时间片，等待下一次调度
//		//线程相当于还是就绪状态，等待CPU的下一次调度 
//	}
//
//	for (int i = 0; i < 100; ++i)
//	{
//		mycount++;
//	}
//}
//int main()
//{
//	list<std::thread> tlist;
//	for (int i = 0; i < 10; ++i)
//	{
//		tlist.push_back(std::thread(task));//启动10个线程 
//	}
//
//	std::this_thread::sleep_for(std::chrono::seconds(3));//主线程睡眠3秒 
//	isReady = true;//所有子线程都进行mycount++ 
//
//	for (std::thread& t : tlist)
//	{
//		t.join();
//	}
//	cout << "mycount:" << mycount << endl;
//
//	return 0;
//}


int main()
{
	shared_ptr<int> sp(new int(10));
	auto sp1(make_shared<int>(10));
	auto sp2 = make_shared<int>(10);

	unique_ptr<int> sp(new int(10));
	auto sp2 = make_unique<int>(10);
	auto sp3(make_unique<int>(10));

	auto sp4(make_unique<int>(10));
	return 0;
}
*/

